﻿//
//    Copyright 2016 KeyleXiao.
//    Contact to Me : Keyle_xiao@hotmail.com 
//
//   	Licensed under the Apache License, Version 2.0 (the "License");
//   	you may not use this file except in compliance with the License.
//   	You may obtain a copy of the License at
//
//   		http://www.apache.org/licenses/LICENSE-2.0
//
//   		Unless required by applicable law or agreed to in writing, software
//   		distributed under the License is distributed on an "AS IS" BASIS,
//   		WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   		See the License for the specific language governing permissions and
//   		limitations under the License.
//

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using IGeneratorContract;
using ConfigGeneratorV2UI.Config;
using System.Linq;

namespace ConfigGeneratorV2UI
{
    public partial class EntranceUI : Form
    {
        public EntranceUI()
        {
            InitializeComponent();
            InitMenuStrip();
            PreloadExcel();
        }

        public Dictionary<string, IPluginContract> ToolPlugins = new Dictionary<string, IPluginContract>();
        public Dictionary<string, ToolStripMenuItem> ToolItems = new Dictionary<string, ToolStripMenuItem>();

        private void InitMenuStrip()
        {
            string pluginPath = Path.Combine(Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location), "Plugin");
            if (!Directory.Exists(pluginPath))
            {
                Directory.CreateDirectory(pluginPath);
                return;
            }

            string[] dll = Directory.GetFiles(pluginPath, "*.dll", SearchOption.TopDirectoryOnly);
            for (int i = 0; i < dll.Length; i++)
            {
                var a = Assembly.LoadFile(dll[i]);
                foreach (Type t in a.GetTypes())
                {
                    if (!typeof(IPluginContract).IsAssignableFrom(t))
                        continue;

                    CreatMenuStrip(a.CreateInstance(t.FullName) as IPluginContract);
                    //ShowMenuStrip(a.CreateInstance(t.FullName) as IPluginContract);
                }
            }
        }

        private void CreatMenuStrip(IPluginContract c)
        {
            var methods = c.GetType().GetMethods();
            for (int i = 0; i < methods.Length; i++)
            {
                object[] objs = methods[i].GetCustomAttributes(typeof(MenuItemAttribute), true);
                if (objs == null)
                    continue;

                for (int index = 0; index < objs.Length; index++)
                {
                    MenuItemAttribute temp = objs[index] as MenuItemAttribute;
                    string[] menus = temp.MenuStr.Split('/');

                    string tempMenuStr = string.Empty;
                    for (int menuIndex = 0; menuIndex < menus.Length; menuIndex++)
                    {
                        string parentPath = tempMenuStr;

                        if (menuIndex == menus.Length - 1)
                        {
                            tempMenuStr += menus[menuIndex];
                        }
                        else
                        {
                            tempMenuStr = string.Format("{0}/{1}/", tempMenuStr, menus[menuIndex]);
                        }

                        if (!ToolItems.ContainsKey(tempMenuStr))
                        {
                            ToolStripMenuItem item = new ToolStripMenuItem();
                            item.Text = GetName(tempMenuStr);
                            item.Name = tempMenuStr;
                            ToolPlugins.Add(tempMenuStr, c);
                            ToolItems.Add(tempMenuStr, item);

                            if (ToolItems.ContainsKey(parentPath))
                            {
                                ToolItems[parentPath].DropDownItems.Add(item);
                            }
                            else { currentMenuStrip.Items.Add(item); }

                            //if node of end
                            if (tempMenuStr.Last() != '/')
                            {
                                item.Click += ToolItemOnClick;
                            }
                        }
                    }
                }

            }
        }
        private string GetName(string str)
        {
            var ss = str.Split('/');
            if (string.IsNullOrEmpty(ss[ss.Length - 1]))
            {
                return ss[ss.Length - 2];
            }
            return ss[ss.Length - 1];
        }

        //private void ShowMenuStrip(IPluginContract c)
        //{
        //    ToolStripMenuItem item = new ToolStripMenuItem();
        //    item.Text = c.PluginName;
        //    item.Click += ToolItemOnClick;
        //    item.Name = ToolPlugins.Count.ToString();
        //    ToolPlugins.Add(ToolPlugins.Count.ToString(), c);
        //    currentMenuStrip.Items.Add(item);
        //}

        private void ToolItemOnClick(object sender, EventArgs e)
        {
            var a = sender as ToolStripMenuItem;

            if (!string.IsNullOrEmpty(ToolPlugins[a.Name].WarningConfirmText))
            {
                var b = MessageBox.Show(ToolPlugins[a.Name].WarningConfirmText + "\n" + ToolPlugins[a.Name].PluginAuthorInfo, "WARNING !", MessageBoxButtons.OKCancel);
                if (b == DialogResult.Cancel)
                    return;
            }

            var methods = ToolPlugins[a.Name].GetType().GetMethods();
            for (int i = 0; i < methods.Length; i++)
            {
                object[] objs = methods[i].GetCustomAttributes(typeof(MenuItemAttribute), true);
                if (objs == null)
                    continue;

                for (int index = 0; index < objs.Length; index++)
                {
                    MenuItemAttribute temp = objs[index] as MenuItemAttribute;
                    if (temp.MenuStr.Replace("/", "") == a.Name.Replace("/", ""))
                    {
                        methods[i].Invoke(ToolPlugins[a.Name], null);
                        if (ToolPlugins[a.Name].ExecutedStatus)
                        {
                            if (!string.IsNullOrEmpty(ToolPlugins[a.Name].ExecutedMsg))
                            {
                                MessageBox.Show(ToolPlugins[a.Name].ExecutedMsg + "\n" + ToolPlugins[a.Name].PluginAuthorInfo);
                            }
                        }
                        else
                        {
                            MessageBox.Show(ToolPlugins[a.Name].ExecutedMsg + "\n" + ToolPlugins[a.Name].PluginAuthorInfo);
                        }
                    }
                }
            }
            //if (Tools[a.Name].Execute(EditorContext.Instance.OutputPath, out msg))
            //{
            //    MessageBox.Show("Execute Success !! \n\n" + msg);
            //}
            //else { MessageBox.Show("Execute Failure !! \n\n" + msg); }
        }




        public void LoadExcelFile(string filePath)
        {

            if (EditorContext.Instance.CustomSetting == null  ||    
                string.IsNullOrEmpty(EditorContext.Instance.CustomSetting.DefaultExportPath))
            {
                SelectPath();
            }

            //Check File Extensions
            if (!filePath.EndsWith("xls", true, null) && !filePath.EndsWith("xlsx", true, null))
                return;

            string msg = string.Empty;

            //Read File 
            var excelInfo = new ExcelReader.ExcelReaderProcess(filePath).GetExcelInfo(out msg);


            if (!string.IsNullOrEmpty(msg))
                MessageBox.Show(string.Format("Infomation\n{0}\n{1}\n{2}", filePath, msg, "Please check the document  : )") );

            if (excelInfo == null )
                return;

            try
            {
                //Get All Sheet info
                for (int i = 0; i < excelInfo.Count; i++)
                {
                    //Check Contains
                    IExcelModel ContainsExcelModel = EditorContext.Instance.ExcelInfos.Keys.Where(item => item.SheetName == excelInfo[i].SheetName && item.WorkBookName == excelInfo[i].WorkBookName).SingleOrDefault();
                    if (ContainsExcelModel != null)
                    {
                        ContainsExcelModel = excelInfo[i];
                        continue;
                    }

                   
                    //add file  to dragdownlist
                    CheckBox c = new CheckBox();
                    c.Location = new System.Drawing.Point(11, 13 + EditorContext.Instance.ExcelInfos.Count * 23);
                    c.Width = 200;
                    c.Text = string.Format("{0} - {1}", excelInfo[i].SheetName, excelInfo[i].WorkBookName);
                    c.Parent = panel1;
                    //Set Sheet Name
                    c.Name = excelInfo[i].SheetName;
                    c.Checked = true;
                    //Add CheckBox Selected Event
                    c.Click += ExcelCk_Click;

                    //Add To Global Chache
                    EditorContext.Instance.ExcelInfos.Add(excelInfo[i], true);

                    //Refresh Plugin's Excel Infomation & Set Plugin Context
                    foreach (var item in ToolPlugins.Values)
                    {
                        item.Context = EditorContext.Instance;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("Infomation\n{0}\n{1}\nExpectopn:{2}", filePath, msg, ex));
            }

            if (!EditorContext.Instance.CustomSetting.DefaultLoadExcelPathList.Contains(filePath))
                EditorContext.Instance.CustomSetting.DefaultLoadExcelPathList.Add(filePath);

            return;
        }

        private void ExcelCk_Click(object sender, EventArgs e)
        {
            var a = sender as CheckBox;
            //Search ExcelInfo where Sheet Name
            var currentExcel = EditorContext.Instance.SearchExcelInfosWithSheetName(a.Name);
            //Set Selected Status
            EditorContext.Instance.ExcelInfos[currentExcel] = a.Checked;
        }

        //public DateTime lastDragTime;

        private void EntranceUI_DragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

                for (int i = 0; i < files.Length; i++)
                {
                    LoadExcelFile(files[i]);
                }
            }
        }

        private void EntranceUI_Load(object sender, EventArgs e)
        {

        }

        public void PreloadExcel()
        {
            if (EditorContext.Instance.CustomSetting== null || string.IsNullOrEmpty(EditorContext.Instance.CustomSetting.DefaultExportPath))
            {
                SelectPath();
            }

            if (EditorContext.Instance.CustomSetting.DefaultLoadExcelPathList != null &&
                EditorContext.Instance.CustomSetting.DefaultLoadExcelPathList.Count >0)
            {
                foreach (string item in EditorContext.Instance.CustomSetting.DefaultLoadExcelPathList)
                {
                    LoadExcelFile(item);
                }
            }
        }

        private void EntranceUI_FormClosed(object sender, FormClosedEventArgs e)
        {
            EditorContext.Instance.UpdateAppSetting();
        }


        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
          
        }


        private void v21ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(EditorContext.Instance.AUTHOR_INFO);
        }

        private void rESETToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SelectPath();
        }

        public void SelectPath() {
            FolderBrowserDialog pathSelector = new FolderBrowserDialog();
            pathSelector.Description = "选择默认导出路径 设置完毕后会保存，如果需要重新设置点击 关于/Reset ";
            pathSelector.ShowDialog();
            EditorContext.Instance.CustomSetting.DefaultExportPath = pathSelector.SelectedPath;
        }

        private void panel1_Scroll(object sender, ScrollEventArgs e)
        {
            this.panel1.VerticalScroll.Value = e.NewValue;

        }

        private void panel1_ControlAdded(object sender, ControlEventArgs e)
        {
            this.panel1.VerticalScroll.Enabled = true;
            this.panel1.VerticalScroll.Visible = true;
            this.panel1.Scroll += panel1_Scroll;
        }
    }
}
